package com.auto.survey.activity.adjustment.adjustment_high.dao

import androidx.room.Dao

import androidx.room.*
import com.auto.survey.activity.adjustment.adjustment_high.entity.*
import kotlinx.coroutines.flow.Flow

@Dao
interface AdjustmentHighDao {
    // ====================
    // Project 相关操作
    // ====================

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertProject(project: Project): Long

    @Update
    suspend fun updateProject(project: Project):Int

    @Delete
    suspend fun deleteProject(project: Project)

    @Transaction
    @Query("SELECT * FROM projects")
    suspend fun getAllProjects(): List<Project>

    @Transaction
    @Query("SELECT * FROM projects WHERE id = :projectId")
    suspend fun getProjectById(projectId: Int): Project?

    @Query("DELETE FROM projects WHERE id = :projectId")
    suspend fun deleteProjectById(projectId: Int)

    // 带流的实时查询
    @Transaction
    @Query("SELECT * FROM projects")
    fun observeAllProjects(): Flow<List<Project>>

    // ====================
    // KnownPoint 相关操作
    // ====================

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertKnownPoint(point: KnownPoint): Long

    @Update
    suspend fun updateKnownPoint(point: KnownPoint):Int

    @Delete
    suspend fun deleteKnownPoint(point: KnownPoint)

    @Query("SELECT * FROM known_points WHERE projectId = :projectId")
    suspend fun getKnownPointsByProjectId(projectId: Int): List<KnownPoint>

    @Query("DELETE FROM known_points WHERE projectId = :projectId")
    suspend fun deleteKnownPointsByProjectId(projectId: Int)

    // ====================
    // UnknownPoint 相关操作
    // ====================

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertUnknownPoint(point: UnknownPoint): Long

    @Update
    suspend fun updateUnknownPoint(point: UnknownPoint):Int

    @Delete
    suspend fun deleteUnknownPoint(point: UnknownPoint)

    @Query("SELECT * FROM unknown_points WHERE projectId = :projectId")
    suspend fun getUnknownPointsByProjectId(projectId: Int): List<UnknownPoint>

    @Query("DELETE FROM unknown_points WHERE projectId = :projectId")
    suspend fun deleteUnknownPointsByProjectId(projectId: Int)

    // ====================
    // Observation 相关操作
    // ====================

    @Insert(onConflict = OnConflictStrategy.REPLACE)
    suspend fun insertObservation(observation: Observation): Long

    @Update
    suspend fun updateObservation(observation: Observation):Int

    @Delete
    suspend fun deleteObservation(observation: Observation)

    @Query("SELECT * FROM observations WHERE projectId = :projectId")
    suspend fun getObservationsByProjectId(projectId: Int): List<Observation>

    @Query("DELETE FROM observations WHERE projectId = :projectId")
    suspend fun deleteObservationsByProjectId(projectId: Int)

    // ====================
    // 关联查询
    // ====================

    @Transaction
    @Query("SELECT * FROM projects WHERE id = :projectId")
    suspend fun getProjectWithAllData(projectId: Int): ProjectWithAllData?

    @Transaction
    @Query("SELECT * FROM projects WHERE id = :projectId")
    suspend fun getProjectWithKnownPoints(projectId: Int): ProjectWithKnownPoints?

    @Transaction
    @Query("SELECT * FROM projects WHERE id = :projectId")
    suspend fun getProjectWithUnknownPoints(projectId: Int): ProjectWithUnknownPoints?

    @Transaction
    @Query("SELECT * FROM projects WHERE id = :projectId")
    suspend fun getProjectWithObservations(projectId: Int): ProjectWithObservations?

    // 带流的实时关联查询
    @Transaction
    @Query("SELECT * FROM projects WHERE id = :projectId")
    fun observeProjectWithAllData(projectId: Int): Flow<ProjectWithAllData?>

    // ====================
    // 批量操作
    // ====================

    @Transaction
    suspend fun insertProjectWithData(project: Project, data: ProjectWithAllData) {
        val projectId = insertProject(project)

        data.knownPoints.forEach { point ->
            insertKnownPoint(point.copy(projectId = projectId.toInt()))
        }

        data.unknownPoints.forEach { point ->
            insertUnknownPoint(point.copy(projectId = projectId.toInt()))
        }

        data.observations.forEach { observation ->
            insertObservation(observation.copy(projectId = projectId.toInt()))
        }
    }

    @Transaction
    suspend fun updateProjectWithData(project: Project, data: ProjectWithAllData) {
        updateProject(project)

        // 先删除旧数据
        deleteKnownPointsByProjectId(project.id)
        deleteUnknownPointsByProjectId(project.id)
        deleteObservationsByProjectId(project.id)

        // 再插入新数据
        data.knownPoints.forEach { point ->
            insertKnownPoint(point.copy(projectId = project.id))
        }

        data.unknownPoints.forEach { point ->
            insertUnknownPoint(point.copy(projectId = project.id))
        }

        data.observations.forEach { observation ->
            insertObservation(observation.copy(projectId = project.id))
        }
    }
}